package com.example.mp3player;

import java.util.ArrayList;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.example.mp3player.Mp3Service.Mp3Binder;

public class Mp3Activity extends Activity {
	private Mp3Service mBoundService;
	private NotificationManager notifManager;
	private Notification notif;
	static boolean showPlay = true;
	private boolean isPaused = false;
	Context context;
	TextView songName;
	TextView duration;
	ImageButton playBut;
	SeekBar seekBar;
	TextView currentDur;
	Thread thr;
	MenuItem loopOne = null;
	MenuItem loopAll = null;
	SharedPreferences shPref;
	Intent service;
	PlayListArrayAdapter playListadapt;
	ListView songList;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_mp3);
		context = this;
		songName = (TextView) findViewById(R.id.songName);
		duration = (TextView) findViewById(R.id.mp3Length);
		seekBar = (SeekBar) findViewById(R.id.mp3ProgressBar);
		playBut = (ImageButton) findViewById(R.id.playTrack);
		currentDur = (TextView) findViewById(R.id.timePassed);
		
		shPref = getSharedPreferences("mp3", Context.MODE_WORLD_READABLE);
		
		/*	Start Mp3Service */
		service = new Intent(this, Mp3Service.class);
		bindService(service, mConnection, BIND_AUTO_CREATE);
		notification();
		
		seekBar.setOnSeekBarChangeListener(onSeekBarChangeListener);
		loadPrefs();
		
		//Problem att det visas dubbla objekt
		addPlayListToView();
		registerForContextMenu(songList);
	}
	
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	getMenuInflater().inflate(R.menu.about, menu);
        getMenuInflater().inflate(R.menu.add_menu, menu);
        getMenuInflater().inflate(R.menu.loop_menu, menu);
        return true;
    }
    
    @Override  
    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {  
    	super.onCreateContextMenu(menu, v, menuInfo);  
    	AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
    	/*	set title to task	*/
    	menu.setHeaderTitle(playListadapt.getSongName(info.position));
    	System.out.println(info.position);
    	/*	add items to menu	*/
    	menu.add(0, 0, 0, "Show file info"); 
    	menu.add(0,1,0, "Share song with SMS");
    	menu.add(0,2,0,"Delete");
    }
	
	//--------------------------------------------------------//
	/*					MediaPlayer Methods					*/
	//--------------------------------------------------------//

	/*	If seekBar is changed update with onSeekBarChangeListener	*/
	SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
		int nowProgress;
		public void onStopTrackingTouch(SeekBar seekBar) {
			if(!mBoundService.playListIsEmpty()){
				seekBar.setProgress(nowProgress);
				mBoundService.getMediaPlayer().seekTo(nowProgress);
			}
		}

		public void onStartTrackingTouch(SeekBar seekBar) {
			
		}

		public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
			nowProgress = progress;				//Update progress
			try{
				if(!mBoundService.playListIsEmpty()){
					/*	Update time left while progress changed	*/
					int minutes = ((mBoundService.getDuration()-progress)/1000)/60;
					int sec = (mBoundService.getDuration()-progress)/1000%60;
					String timeLeft = minutes + ":" + sec;
					currentDur.setText(timeLeft);
				}
			}catch(RuntimeException e){
				e.printStackTrace();
			}
		}
	};

	public void prevTrack(View v){
		try{
			mBoundService.prev();
			songName.setText(mBoundService.getSongName());
			duration.setText(mBoundService.getSongLength());
			seekBar.setMax(mBoundService.getDuration());
		}catch(NullPointerException e){
			e.printStackTrace();
		}
	}

	public void nextTrack(View v){
		try{
			mBoundService.next();
			songName.setText(mBoundService.getSongName());
			duration.setText(mBoundService.getSongLength());
			seekBar.setMax(mBoundService.getDuration());
		}catch(NullPointerException e){
			e.printStackTrace();
		}
	}

	public void playTrack(View v){
		setThread();

		/*	Check if gonna play or pause	*/
		if(showPlay && !mBoundService.playListIsEmpty() && !mBoundService.isPlaying()){
			mBoundService.play();
			/*	Set seekBar maximum	*/
			seekBar.setMax(mBoundService.getDuration());
			/*	Set song duration*/
			duration.setText(mBoundService.getSongLength());

			/*	Change to pause icon on play/pause button	*/
			playBut.setImageResource(android.R.drawable.ic_media_pause);
			showPlay = false;	//	show play-icon
			isPaused = false;

			/*	Check if thread already started	*/
			if(mBoundService.playListIsEmpty() && !isPaused){
				thr.start();
				songName.setText(mBoundService.getSongName());
			}
			/*	resume Thread when songs been paused	*/
			else{
				if(thr != null){
					Thread paused = thr;
					thr = null;
					paused.interrupt();
				}
			}
		}
		else{
			isPaused = true;
			thr = null;
			mBoundService.pause();
			playBut.setImageResource(android.R.drawable.ic_media_play);
			showPlay = true;
		}
	}
	
	private void setThread(){
		final Handler handler = new Handler();
		/*	Thread to update SeekBar	*/
		thr = new Thread(new Runnable(){
			public void run() {
				if(!mBoundService.playListIsEmpty()){
					handler.postDelayed(this, 1000);	//make thread update every second
					seekBar.setIndeterminate(false);

					/*	Check if song is complete and next song is playing	*/
					if(!mBoundService.playListIsEmpty() || (songName.getText() != mBoundService.getSongName() && mBoundService.isPlaying())){
						/*	Update	information	*/
						seekBar.setMax(mBoundService.getDuration());
					}
					/*	Update seekBar position if MediaPlayer is playing	*/
					if(mBoundService.isPlaying()){
						seekBar.setProgress(mBoundService.getCurrentPosition());


						/*	Code that need to be run in main Thread	*/
						runOnUiThread(new Runnable() {
							public void run() {
								/*	Update the time left	*/
								if(!mBoundService.playListIsEmpty() || (songName.getText() != mBoundService.getSongName())){
									duration.setText(mBoundService.getSongLength());
									songName.setText(mBoundService.getSongName());
								}
								currentDur.setText(mBoundService.getTimePassed());
							}
						});
					}
					/*	If playlist is complete */
					else if(mBoundService.getIsComplete()){
						playBut.setImageResource(android.R.drawable.ic_media_play);		//Change to play icon
						songName.setText(mBoundService.getSongName());					//Get Song-name for new song
						mBoundService.setIsComplete(false);								//reset isComplete
						seekBar.setProgress(0);											//Reset seekbar
						thr = null;														//Kill thread
						showPlay = true;
					}
				}
			}
		});
	}
	
	//--------------------------------------------------------//
	/*			Activity Methods (e.g onResume) 				*/
	//--------------------------------------------------------//

	@Override
	public void onPause(){
		super.onPause();
		/*	Place notification	*/
		if(mBoundService.isPlaying()){
			notifManager.notify(1, notif);		
		}
		savePrefs();
	}

	@Override
	public void onResume(){
		/*	Remove notification	*/
		notifManager.cancel(1);
		addPlayListToView();
		loadPrefs();
		super.onResume();
	}	
	
	@Override
	public void onDestroy(){
		super.onDestroy();
	}
	
	//--------------------------------------------------------//
	/*					Service Methods						*/
	//--------------------------------------------------------//

	/*	Create connection to be able to get information from service */
	private ServiceConnection mConnection = new ServiceConnection(){
		public void onServiceConnected(ComponentName name, IBinder service) {
			Mp3Binder mBinder = (Mp3Binder)service;	//Binder in service
			mBoundService = mBinder.getService();
		}

		/*	on crash or if anything other fail with the service	*/
		public void onServiceDisconnected(ComponentName name) {
			unbindService(mConnection);
		}
	};
	
	
	//--------------------------------------------------------//
	/*						Click Methods					*/
	//--------------------------------------------------------//
    
    @Override  
    public boolean onContextItemSelected(MenuItem item) {  
    	AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
        /*	check wich item is selected	*/
    	if(item.getItemId() == 0)	
    	{
    		AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
    		alertBuilder.setTitle(playListadapt.getSongName(info.position));
    		alertBuilder.setMessage("Location: " + mBoundService.getPlaylist().get(info.position) 
    				+ "\nLength: " + playListadapt.getSongLength(info.position));
    		
    		alertBuilder.setNegativeButton("Ok", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					dialog.cancel();					
				}
			});    		
    		AlertDialog dialog = alertBuilder.create();
    		dialog.show();
        }  
    	else if(item.getItemId() == 1){
    		Intent i = new Intent(Intent.ACTION_SEND);
    		i.setType("text/plain");
    		i.putExtra(Intent.EXTRA_TEXT, playListadapt.getSongName(info.position));
    		startActivity(i);
    	}
    	else if(item.getItemId() == 2){
    		Toast.makeText(context, "Removed: " + playListadapt.getSongName(info.position), Toast.LENGTH_SHORT).show();
    		if(mBoundService.getSongCount() != 0){
    			mBoundService.setSongCount(1);
    		}
    		if(mBoundService.getSongCount() == info.position){
    			mBoundService.getMediaPlayer().stop();
    			mBoundService.getMediaPlayer().reset();
    			mBoundService.setSongCount(0);
    		}
    		mBoundService.getPlaylist().remove(info.position);
    		playListadapt.notifyDataSetChanged();
    	}
        else {
        	return false;
        }  
    return true;  
    }
    
    private String choice;
    public boolean onOptionsItemSelected(MenuItem item){
    	switch (item.getItemId()) {
    		case R.id.about_button:
        		AlertDialog.Builder aboutBuilder = new AlertDialog.Builder(context);
        		
        		aboutBuilder.setTitle("Project Mp3");       		
        		aboutBuilder.setMessage("Project Mp3-player!\nCreated by: Pontus Nyberg \n2012")
        		.setNeutralButton("OK", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						//Done showing about-dialog
					}
				});
        		
        		AlertDialog alertDialog = aboutBuilder.create();
        		alertDialog.show();
        		return true;
        	case R.id.add:
        		browseFiles();
        		return true;
        	case R.id.loop:
        		AlertDialog.Builder builder = new AlertDialog.Builder(context);
        		builder.setTitle(R.string.mp3_loop_menu);
        		
        		final CharSequence[] loop_choices = {"Loop One", "Loop All"};
        		
        		builder.setSingleChoiceItems(loop_choices, -1, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						if(which == 0){
							mBoundService.getMediaPlayer().setLooping(true);
	        				mBoundService.setLoopAll(false);
	        				choice = "Loop One";
						}
						else if(which == 1){
							mBoundService.setLoopAll(true);
		        			mBoundService.getMediaPlayer().setLooping(false);
		        			choice = "Loop All";
						}
					}
				}).setPositiveButton("Choose", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						Toast.makeText(context, choice+" is selected!", Toast.LENGTH_SHORT).show();						
					}
				}).setNegativeButton("Remove looping", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {
						mBoundService.setLoopAll(false);	
						mBoundService.getMediaPlayer().setLooping(false);
					}
				});
        		AlertDialog alert = builder.create();
        		alert.show();
        		return true;
        	default:
                return super.onOptionsItemSelected(item);
    	}
    }
	
	/*	Start filebrowser	*/
	public void browseFiles(){
		Toast.makeText(context, "To add a folder use long click\nand to add a file click it.",  Toast.LENGTH_LONG).show();
		Intent intent = new Intent(context, FileBrowser.class);
		startActivityForResult(intent, 0);
	}

    
	//--------------------------------------------------------//
	/*						Save&Load						*/
	//--------------------------------------------------------//
	
	private void savePrefs(){
		Editor edit = shPref.edit();
		try{
			edit.putString("timeLeft", (String) currentDur.getText());
			edit.putString("songName", (String) songName.getText());
			edit.putString("songLength", (String) duration.getText());
			edit.putInt("playListLength", mBoundService.getPlaylist().size());
			/*	Add all songs from playList*/
			for(int i = 0; i < mBoundService.getPlaylist().size(); i++){
				edit.putString("song" + i, mBoundService.getPlaylist().get(i));
			}
			edit.putInt("seekBarPos", seekBar.getProgress());
			edit.putInt("songTime", mBoundService.getCurrentPosition());
		}catch(NullPointerException e){
			e.printStackTrace();
		}catch(IllegalStateException e){
			e.printStackTrace();
		}catch(IllegalArgumentException e){
			e.printStackTrace();
		}catch(RuntimeException e){
			e.printStackTrace();
		}
		edit.commit();
	}
	
	private void loadPrefs(){
		try{
			currentDur.setText(shPref.getString("timeLeft", "00:00"));
			duration.setText(shPref.getString("songLength", "00:00"));
			songName.setText(shPref.getString("songName", ""));
			if(mBoundService.playListIsEmpty()){
				int tmpInt = shPref.getInt("playListLength", 0);
				for(int i = 0; i < tmpInt; i++){
					String tmpStr = shPref.getString("song" + i, null);
					if(tmpStr != null){
						mBoundService.addSong(tmpStr);
					}
				}
			}
			seekBar.setProgress(shPref.getInt("seekBarPos", 0));
			if(!mBoundService.isPlaying()){
				mBoundService.getMediaPlayer().seekTo(shPref.getInt("songTime", 0));
			}
		}catch(NullPointerException e){
			e.printStackTrace();
		}catch(IllegalStateException e){
			e.printStackTrace();
		}catch(IllegalArgumentException e){
			e.printStackTrace();
		}catch(RuntimeException e){
			e.printStackTrace();
		}
	}
	
	//--------------------------------------------------------//
	/*						Other							*/
	//--------------------------------------------------------//
	
	/*	Get results from browser	*/
	protected void onActivityResult(int requestCode, int resultCode, Intent data){
		if(resultCode == Activity.RESULT_OK){
			int request = data.getIntExtra("requestCode", 0);
			if(request == 0){
				String tmpStr = data.getStringExtra("song");
				mBoundService.addSong(tmpStr);
			}
			else if(request == 1){
				ArrayList<String> songs = data.getStringArrayListExtra("songList");
				for(int i = 0; i < songs.size(); i++){
					mBoundService.addSong(songs.get(i));
				}
			}
		}
	}
	
	@SuppressWarnings("deprecation")
	private void notification(){
		/* 1. Setup Notification Builder */			
		Notification.Builder builder = new Notification.Builder(context); 

		/* 2. Configure Notification Alarm */
		builder.setSmallIcon(android.R.drawable.ic_media_play)
		.setWhen(System.currentTimeMillis())
		.setAutoCancel(true);

		/* 3. Configure Drop-down Action */
		Intent resume = new Intent(context, Mp3Activity.class);	// Notification intent
		resume.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
		PendingIntent notifIntent = PendingIntent.getActivity(context, 0, resume, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
		builder.setContentIntent(notifIntent).
		setContentTitle("Mp3 Player").
		setContentText("Click to resume player");

		/* 4. Create Notification and use Manager to launch it */
		notif = builder.getNotification();
		String ns = Context.NOTIFICATION_SERVICE;
		notifManager = (NotificationManager) context.getSystemService(ns);
	}
	

	public void addPlayListToView(){
		songList = (ListView) findViewById(R.id.playList);
		
		songList.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
				if(!mBoundService.isPlaying() && !mBoundService.playListIsEmpty()){
					setThread();
					thr.start();
					/*	Change to pause icon on play/pause button	*/
					playBut.setImageResource(android.R.drawable.ic_media_pause);
					mBoundService.changeSong(position);
				}
				else{
					mBoundService.changeSong(position);
					if(thr != null && !mBoundService.playListIsEmpty()){
						Thread paused = thr;
						thr = null;
						paused.interrupt();
					}
					if(!mBoundService.playListIsEmpty()){
						setThread();
						thr.start();
					}
				}
			}
		});

		try{
			if(!mBoundService.playListIsEmpty() && playListadapt == null){
				playListadapt = new PlayListArrayAdapter(context, R.layout.playlist, mBoundService.getPlaylist());
				songList.setAdapter(playListadapt);
			}
		}catch(NullPointerException e){
			e.printStackTrace();
		}
	}
}
